import Fill from "ol/style/Fill";
import Icon from "ol/style/Icon";
import Stroke from "ol/style/Stroke";
import Style from "ol/style/Style";
import Text from "ol/style/Text";
import { transform } from "ol/proj";
import { OverlayManager } from "../manager/overlayManager";
import { MapManager } from "../manager/MapManage";
import { LayerManager } from "../manager/LayerManager";
import { DoubleClickZoom } from "ol/interaction";
import Draw from "ol/interaction/Draw";
import { LayerConstant } from "../manager/LayerConstant";
import { InteractionTools } from "./interactionTools";
import { unByKey } from "ol/Observable";
import { getArea, getLength } from "ol/sphere";
import { LineString, Point, Polygon } from "ol/geom";
import { Feature, Overlay } from "ol";
export class InteractionManager {
  // 测量交互相关属性
  measureLayerArrays = [];
  measureTooltipElement = null;
  measureTooltip = null;
  measureTooltipArrays = [];
  helpTooltipElement = null;
  helpTooltip = null;
  measureDrawStartListener = null; // 测量绘制开始事件监听
  measureDrawEndListener = null; // 测量绘制结束事件监听
  pointerMoveListener = null; //测量鼠标指针移动监听
  measureFeature = null;
  meaFeatureListener = null;
  meaClickListener = null;
  meaDblClickListener = null;
  meaGeomValue = null; // 测量结果值
  pointlist = []; // 线上面的点
  gpsStartPointFeature = null;
  gpsTrackVectorLayer = null;
  single = false;
  measureInteraction;

  measureLayer = null; //绘制的线的图层
  constructor(map) {
    this.mapManager = new MapManager(map);
    this.layerManager = new LayerManager(map);
    this.overlayManager = new OverlayManager(map);
    this.interactionTools = new InteractionTools(map);
    this.currentMap = map;
    this.addIndustryLayerHover();
    // this.initIndustryLayerHover(this.currentMap, mapManager, overlayManager);
  }
  // 地图专题图层要素默认鼠标hover交互初始化
  mapMoveEndListener(event) {
    // let overlayer;
    // let pointmoveEle
    // if (event.feature || event.features) {
    //   this.mapManager.changeMapCursor("select");
    //   let geometry = event.data
    //     ? event.data.geometry
    //     : {
    //         type: "point",
    //         points: [
    //           {
    //             x: event.position[0],
    //             y: event.position[1],
    //           },
    //         ],
    //       };
    //   let hoverText =
    //     event.hoverContent ||
    //     (event.data && event.data.data && event.data.data.hoverText);
    //   // console.warn(that.hoverText + '==???' + hoverText)
    //   if (hoverText) {
    //     // that.hoverText = hoverText
    //     let data = {
    //       id: "pointermove",
    //       name: hoverText,
    //       geometry,
    //       insertFirst: false,
    //     };
    //     pointmoveEle = document.createElement("div");
    //     pointmoveEle.className = "feature-pointer-move";
    //     // let content = data.name || '暂无提示'
    //     let content = data.name;
    //     if (!content) {
    //       return;
    //     }
    //     pointmoveEle.innerHTML = `<p class="content">${content}</p>`;
    //     overlayer = new Ovelayer(data, pointmoveEle);
    //     if (!this.currentMap.getOverlayById("pointermove")) {
    //       const overlayObj = overlayer.getOverlay();
    //       overlayObj.setOffset([0, -20]);
    //       this.currentMap.addOverlay(overlayObj);
    //     }
    //   } else {
    //     // let data = {
    //     //   id: 'pointermove',
    //     //   // name: event.data.name,
    //     //   geometry,
    //     // }
    //     if (pointmoveEle) {
    //       pointmoveEle.parentNode.removeChild(pointmoveEle);
    //     }
    //     overlayer = null;
    //     pointmoveEle = null;
    //     if (this.currentMap.getOverlayById("pointermove")) {
    //       this.overlayManager.removeOverlayById("pointermove");
    //     }
    //   }
    // } else {
    //   this.mapManager.changeMapCursor("default");
    //   if (pointmoveEle) {
    //     pointmoveEle.parentNode.removeChild(pointmoveEle);
    //   }
    //   overlayer = null;
    //   pointmoveEle = null;
    //   if (this.currentMap.getOverlayById("pointermove")) {
    //     this.overlayManager.removeOverlayById("pointermove");
    //   }
    // }
  }

  addIndustryLayerHover() {
    this.mapManager.onMapEvent("pointermove", this.mapMoveEndListener);
  }

  /**
   * 创建点要素
   * @param callback 回调函数，返回点要素的坐标给回调函数
   */
  createMarkerFeature(callback, styleconfig) {
    const marker = require("../assets/mapimg/marker.png");
    const defaulStyle = new Style({
      image: new Icon({
        src: marker,
        offset: [0, 0],
        size: [32, 62],
      }),
      zIndex: 11,
    });
    const style = styleconfig ? new Style(styleconfig).style : defaulStyle;
    this.drawFeature("Point", style, (feature) => {
      const geom = feature.getGeometry();
      let coordinate = geom.getLastCoordinate();
      let wkt = transform(
        [coordinate[0], coordinate[1]],
        "EPSG:3857",
        "EPSG:4326"
      );
      let data = {
        mFeature: feature,
        type: "Point",
        position: coordinate,
        feature: feature,
        wkt: "POINT(" + wkt[0] + " " + wkt[1] + ")",
        position3857: [wkt[0], wkt[1]],
      };
      callback(data);
    });
  }

  /**
   * 绘制要素
   * @param type 绘制类型
   * @param style 绘制样式，可不传
   * @param callback 绘制回调函数，可不传，回调返回当前绘制要素
   */
  drawFeature(type, style, callback) {
    let drawInteraction = this.drawInteraction(type, style);
    this.drawEndEvent(drawInteraction, this.mapManager, this, callback);
  }

  /**
   * 监听绘制事件结束
   * @param drawInteraction 绘制事件对象
   * @param mapManager 当前地图管理类对象
   * @param callback 回调函数，返回当前绘制要素给回调函数
   */
  drawEndEvent(drawInteraction, mapManager, interactionManager, callback) {
    let feature = null;
    this.pointDrawInteraction = drawInteraction;
    drawInteraction.on("drawend", (event) => {
      feature = event.feature;
      if (callback) {
        callback(feature);
      }
      this.currentMap.removeInteraction(drawInteraction);
      this.addIndustryLayerHover();
      mapManager.changeMapCursor("default");
    });
  }
  /**
   * 创建绘制对象
   * @param type 绘制类型
   * @param style 绘制时样式，可不传
   */
  drawInteraction(type, style) {
    if (!this.layerManager.getDrawLayer()) {
      this.layerManager.createDrawLayer(style);
    }
    const drawLayer = this.layerManager.getDrawLayer();
    console.log(drawLayer);

    style && drawLayer.layer.setStyle(style);
    this.mapManager.changeMapCursor("draw");
    this.removeIndustryLayerHover();
    let drawInteraction;
    if (type === "Freehand") {
      drawInteraction = this.addDrawInteraction(
        drawLayer.layer,
        "Polygon",
        true,
        true,
        style
      );
    } else {
      drawInteraction = this.addDrawInteraction(
        drawLayer.layer,
        type,
        false,
        true,
        style
      );
    }
    return drawInteraction;
  }

  /**
   * 新增一个绘制交互事件
   * @param layer 绘制的矢量图层
   * @param type 绘制类型
   * @param freehand 是否是徒手多边形
   * @param stopClick 是否阻止默认地图点击、双击事件
   * @param style 矢量图层样式
   */
  addDrawInteraction(layer, type, freehand, stopClick, style) {
    let geoFun;
    if (type === "Box") {
      geoFun = Draw.createBox();
      type = "Circle";
    }
    let draw = new Draw({
      source: layer.getSource(),
      type: type,
      freehand: freehand,
      stopClick: stopClick ? stopClick : false,
      style: style,
      geometryFunction: geoFun ? geoFun : undefined,
    });
    let drawInteraction = draw;
    this.currentMap.addInteraction(drawInteraction);
    return drawInteraction;
  }

  // 移除地图专题图层默认hover事件
  removeIndustryLayerHover() {
    this.mapManager.unMapEvent("pointermove", this.mapMoveEndListener);
  }

  // 清除当前绘制的点图层
  clearDrawLayerFeatures() {
    const layer = this.layerManager.getDrawLayer();
    if (layer) {
      layer.layer.getSource().clear();
    }
  }

  /**
   * 开始地图测量
   * @param type 测量类型，测长度或面积
   * @param callback
   */
  startMapMeasure(type, param, callback) {
    this.closeMapMeasure();
    this.removeMapInteraction(DoubleClickZoom);
    this.removeIndustryLayerHover();
    this.mapManager.changeMapCursor("draw");
    let style =param.isModifystyle ? new Style(param.style) : LayerConstant.DEFAULT_MEASURE_STYLE

    let measureLayer = this.layerManager.createMeasureLayer(style);
    let measureInteraction = this.interactionTools.addDrawInteraction(
      measureLayer.layer,
      type,
      false,
      false
    );
    this.initMouseMoveHelpTooltip();
    this.measureDrawStartEvent(measureInteraction, measureLayer);
    this.measureDrawEndEvent(
      measureInteraction,
      this.mapManager,
      this.layerManager.getMeasureLayers(),
      measureLayer,
      (res) => {
        callback(res);
      }
    );
    this.measureInteraction = measureInteraction;
  }

  /**
   * 移除指定交互对象
   * @param interaction 交互对象
   */
  removeMapInteraction(interaction) {
    this.currentMap.getInteractions().forEach((item) => {
      if (item instanceof interaction) {
        this.currentMap.removeInteraction(item);
      }
    });
  }

  // 初始化测量提示工具
  initMouseMoveHelpTooltip() {
    this.createHelpTooltop();
    this.pointerMoveListener = this.currentMap.on("pointermove", (event) => {
      if (event.dragging) {
        return;
      }
      let helpMsg = "单击确定起点";
      if (this.measureFeature) {
        helpMsg = "单击选中下一点,</br>双击结束测量";
      }
      this.helpTooltipElement.innerHTML = helpMsg;
      this.helpTooltip.setPosition(event.coordinate);
      this.helpTooltipElement.style.display = "block";
    });
  }
  /**
   * 测量绘制开始事件
   * @param drawInteraction 绘制交互对象
   * @param layer 当前绘制的测量图层
   */
  measureDrawStartEvent(drawInteraction, layer, isPoint) {
    this.createMeasureTooltip(layer.id);
    let measureLayerSource = layer.layer.getSource();
    this.pointlist = [];
    this.measureDrawStartListener = drawInteraction.on(
      "drawstart",
      (event) => {
        this.measureFeature = event.feature;
        let tooltopCoor = event.coordinate;
        this.meaFeatureListener = this.measureFeature
          .getGeometry()
          .on("change", (event) => {
            let geom = event.target;
            if (geom instanceof LineString) {
              this.meaGeomValue = this.formatLength(getLength(geom));
              this.measureTooltipElement.innerHTML =
                "总距离: " + this.meaGeomValue;
              tooltopCoor = geom.getLastCoordinate();
            } else if (geom instanceof Polygon) {
              this.meaGeomValue = this.formatArea(getArea(geom));
              this.measureTooltipElement.innerHTML =
                "总面积: " + this.meaGeomValue;
              tooltopCoor = geom.getInteriorPoint().getCoordinates();
            }
            this.measureTooltip.setPosition(tooltopCoor);
          });

        this.meaClickListener = this.currentMap.on("singleclick", (event) => {
          let point = new Point(event.coordinate);
          this.pointlist.push(event.coordinate);
          console.log("是否画起终点", isPoint);
          // 画起点
          if (!this.single && isPoint) {
            this.single = true;
            this.gpsStartPointFeature = this.createStartPoint(point);
            measureLayerSource.addFeature(this.gpsStartPointFeature);
          } else {
            const currentFeature = new Feature({
              geometry: point,
            });
            measureLayerSource.addFeature(currentFeature);
          }
        });

        this.meaDblClickListener = this.currentMap.once("dblclick", (event) => {
          let point = new Point(event.coordinate);
          this.pointlist.push(event.coordinate);
          measureLayerSource.addFeature(new Feature(point));
        });
      },
      this
    );
  }

  // 格式化测量长度值
  formatLength(output) {
    let result;
    if (output > 100) {
      result = Math.round((output / 1000) * 100) / 100 + " " + "km";
    } else {
      result = Math.round(output * 100) / 100 + " " + "m";
    }
    return result;
  }
  //格式化测量面积值
  formatArea(area) {
    let result;
    if (area > 10000) {
      result =
        Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
    } else {
      result = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
    }
    return result;
  }

  // 创建开始点
  createStartPoint(pointData) {
    const startImg = require("../assets/mapimg/startpoint.png");
    const startPointStyle = new Style({
      image: new Icon({
        src: startImg,
        size: [26, 38],
      }),
    });
    // const startPointGeom = new ol.geom.Point([pointData.x, pointData.y])
    const pointFeature = new Feature({
      geometry: pointData,
      type: "startPoint",
    });
    pointFeature.setStyle(startPointStyle);
    return pointFeature;
  }

  /**
   * 测量绘制结束事件
   * @param drawInteraction 绘制交互对象
   * @param mapManager 地图管理对象，用于改变鼠标样式
   * @param measurelayerArray 传入测量图层数组
   */
  measureDrawEndEvent(
    drawInteraction,
    mapManager,
    measurelayerArray,
    layer,
    callback,
    isPoint,
    isDel
  ) {
    this.measureLayerArrays = measurelayerArray;
    this.measureDrawEndListener = drawInteraction.on(
      "drawend",
      (event) => {
        this.measureTooltipElement.className =
          "map-measure-tooltip map-measure-tooltip-static";
        if (!isDel) {
          let deleteBtn = this.createDeleteMeasureBtn(callback);
          this.measureTooltipElement.appendChild(deleteBtn);
        }
        setTimeout(() => {
          // 绘制结束，画终点
          if (isPoint) {
            let measureLayerSource = layer.layer.getSource();
            let endPoint = this.pointlist[this.pointlist.length - 1];
            let point = new Point(endPoint);
            this.gpsStartPointFeature = this.createEndPoint(point);
            measureLayerSource.addFeature(this.gpsStartPointFeature);
          }
        }, 500);
        this.measureTooltip.setOffset([0, -20]);
        this.measureFeature = null;
        this.measureTooltipElement = null;
        unByKey(this.meaFeatureListener);
        unByKey(this.meaClickListener);
        this.removeMeasureEventListener();
        this.removeHelpTooltip();
        setTimeout(() => {
          this.addInteraction(new DoubleClickZoom());
          callback({
            measureResult: this.meaGeomValue,
            measureLayer: measurelayerArray,
            pointlist: this.pointlist,
          });
        }, 1000);
        mapManager.changeMapCursor("default");
      },
      this
    );
    return this.meaGeomValue;
  }

  // 移除测量绘制事件
  removeMeasureEventListener() {
    this.currentMap.removeInteraction(this.interactionTools.drawInteraction);
    unByKey(this.measureDrawStartListener);
    unByKey(this.measureDrawEndListener);
    unByKey(this.pointerMoveListener);
  }

  // 删除测量帮助提示框
  removeHelpTooltip() {
    if (this.helpTooltipElement) {
      this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
      this.helpTooltipElement = null;
      this.currentMap.removeOverlay(this.helpTooltip);
    }
  }

  // 创建测量结果提示窗口
  createMeasureTooltip(layerid) {
    this.removeMeasureTooptip();
    this.measureTooltipElement = document.createElement("div");
    this.measureTooltipElement.className =
      "map-measure-tooltip map-measure-tooltip-start";
    this.measureTooltipElement.setAttribute("name", layerid);
    this.measureTooltip = new Overlay({
      element: this.measureTooltipElement,
      offset: [-10, -15],
      positioning: "bottom-center",
    });
    this.currentMap.addOverlay(this.measureTooltip);
    this.measureTooltipArrays.push({
      id: layerid,
      tooltip: this.measureTooltip,
    });
  }

  /**
   * 添加一个交互对象
   * @param interaction
   */
  addInteraction(interaction) {
    this.currentMap.addInteraction(interaction);
  }

  createDeleteMeasureBtn(callback) {
    let deleteBtn = document.createElement("button");
    const deleteImg = require("../assets/mapimg/delete.png");
    deleteBtn.style.width = "16px";
    deleteBtn.style.height = "16px";
    deleteBtn.style.background = `url("${deleteImg}") no-repeat`;
    deleteBtn.style.cursor = "pointer";
    deleteBtn.className = "map-measure-delete";
    deleteBtn.addEventListener(
      "click",
      (event) => {
        let layerId = event.target.parentNode.getAttribute("name");
        console.log("删除测量图层：", layerId);
        this.removeMeaLayerById(
          this.measureLayerArrays,
          this.measureTooltipArrays,
          layerId
        );
        callback({
          measureResult: this.meaGeomValue,
          pointlist: this.pointlist,
          isDels: true,
        });
        this.single = false;
        this.removeMeasureTooptip();
      },
      false
    );
    return deleteBtn;
  }

  // 移除测量结果提示框
  removeMeasureTooptip() {
    if (this.measureTooltipElement) {
      this.measureTooltipElement.parentNode.removeChild(
        this.measureTooltipElement
      );
      this.measureTooltipElement = null;
      this.currentMap.removeOverlay(this.measureTooltip);
    }
  }

  /**
   * 通过测量图层id移除对应测量结果及图层
   * @param measurelayerArray 测量图层数组
   * @param measureTooltips 测量提示标注物数组
   * @param id 对应测量结果id
   */
  removeMeaLayerById(measurelayerArray, measureTooltips, id) {
    measurelayerArray.forEach((layer) => {
      if (layer.id === id) {
        this.currentMap.removeLayer(layer.layer);
      }
    });
    measureTooltips.forEach((tooltip) => {
      if (tooltip.id === id) {
        this.currentMap.removeOverlay(tooltip.tooltip);
      }
    });
    // this.measureInteraction.measureInstance = null;
  }

  /**
   * @description 关闭测量事件
   */
  closeMapMeasure() {
    this.measureFeature = null;
    this.measureTooltipElement = null;
    unByKey(this.meaFeatureListener);
    unByKey(this.meaClickListener);
    this.removeMeasureEventListener();
    this.removeHelpTooltip();
  }

  // 创建测量帮助提示框
  createHelpTooltop() {
    this.removeHelpTooltip();
    this.helpTooltipElement = document.createElement("div");
    this.helpTooltipElement.className = "map-tooltip";
    this.helpTooltip = new Overlay({
      element: this.helpTooltipElement,
      offset: [15, 15],
      positioning: "center-left",
    });
    this.currentMap.addOverlay(this.helpTooltip);
  }
}
